package com.qh.resourcehub.program.qzt.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qh.resourcehub.program.access.service.AccessExamineService;
import com.qh.resourcehub.program.audit.service.SourceCodeAuditExamineService;
import com.qh.resourcehub.program.dto.*;
import com.qh.resourcehub.program.entity.UserEntity;
import com.qh.resourcehub.program.firewall.service.FirewallExamineService;
import com.qh.resourcehub.program.mapper.UserInfoMapper;
import com.qh.resourcehub.program.netmapping.service.NetMappingExamineService;
import com.qh.resourcehub.program.qzt.dto.QztTodoDto;
import com.qh.resourcehub.program.qzt.service.QztTodoService;
import com.qh.resourcehub.program.qzt.vo.UserTodoDetailVO;
import com.qh.resourcehub.program.security.service.SecurityAssessmentExamineService;
import com.qh.resourcehub.program.virtual.service.VirtualExamineService;
import com.qh.resourcehub.program.vo.*;
import com.qh.resourcehub.program.vpn.service.VpnExamineService;
import com.qh.resourcehub.program.wifi.service.WifiExamineService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class QztTodoServiceImpl implements QztTodoService {

    private static final Logger logger = LoggerFactory.getLogger(QztTodoServiceImpl.class);

    @Value("${qzt.api.url:http://10.1.65.76:7001}")
    private String qztApiUrl;

    @Value("${qzt.api.username:}")
    private String qztUsername;

    @Value("${qzt.api.password:}")
    private String qztPassword;

    @Value("${qzt.sys.code:057003}")
    private String sysCode;

    @Value("${qzt.sys.name:青海省气象局基础资源申请系统}")
    private String sysName;

    @Value("${app.base.url:http://10.181.23.237/index.html#/inventoryManagement/list/Home?userCode=}")
    private String appBaseUrl;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private VirtualExamineService virtualExamineService;

    @Autowired
    private WifiExamineService wifiExamineService;

    @Autowired
    private VpnExamineService vpnExamineService;

    @Autowired
    private FirewallExamineService firewallExamineService;

    @Autowired
    private NetMappingExamineService netMappingExamineService;

    @Autowired
    private AccessExamineService accessExamineService;

    @Autowired
    private SourceCodeAuditExamineService sourceCodeAuditExamineService;

    @Autowired
    private SecurityAssessmentExamineService securityAssessmentExamineService;

    @Override
    public List<UserTodoDetailVO> queryAllUserTodos() {
        List<UserTodoDetailVO> allTodos = new ArrayList<>();
        List<UserEntity> userEntities = userInfoMapper.selectList(null);

        for (UserEntity userEntity : userEntities) {
            String userCode = userEntity.getUserCode();
            
            UserDto userDto = new UserDto();
            userDto.setUserCode(userCode);
            List<UserVo> userInfoList = userInfoMapper.queryUserInfo(userDto);
            if (userInfoList == null || userInfoList.isEmpty()) {
                continue;
            }
            UserVo userInfo = userInfoList.get(0);

            VirtualDto virtualDto = new VirtualDto();
            virtualDto.setUserCode(userCode);
            List<VirtualVo> virtualVos = virtualExamineService.queryVirtualExamineDataNum(virtualDto);
            if (virtualVos != null) {
                for (VirtualVo vo : virtualVos) {
                    UserTodoDetailVO todo = new UserTodoDetailVO();
                    todo.setUserCode(userCode);
                    todo.setUserName(userEntity.getName());
                    todo.setDeptCode(userInfo.getCode());
                    todo.setOrgCode(userInfo.getOrgCode());
                    todo.setBusinessId(vo.getProcessId());
                    todo.setBusinessType("virtual");
                    todo.setBusinessTypeName("虚拟机审批");
                    todo.setTitle("虚拟机申请-" + vo.getApplicantUser());
                    todo.setLink(appBaseUrl + "/#/examine/virtual?processId=" + vo.getProcessId());
                    allTodos.add(todo);
                }
            }

            WifiDto wifiDto = new WifiDto();
            wifiDto.setUserCode(userCode);
            List<WifiVo> wifiVos = wifiExamineService.queryWifiExamineDataNum(wifiDto);
            if (wifiVos != null) {
                for (WifiVo vo : wifiVos) {
                    UserTodoDetailVO todo = new UserTodoDetailVO();
                    todo.setUserCode(userCode);
                    todo.setUserName(userEntity.getName());
                    todo.setDeptCode(userInfo.getCode());
                    todo.setOrgCode(userInfo.getOrgCode());
                    todo.setBusinessId(vo.getProcessId());
                    todo.setBusinessType("wifi");
                    todo.setBusinessTypeName("WiFi审批");
                    todo.setTitle("WiFi申请-" + vo.getApplicantUser());
                    todo.setLink(appBaseUrl + "/#/examine/wifi?processId=" + vo.getProcessId());
                    allTodos.add(todo);
                }
            }

            VpnDto vpnDto = new VpnDto();
            vpnDto.setUserCode(userCode);
            List<VpnVo> vpnVos = vpnExamineService.queryVpnExamineDataNum(vpnDto);
            if (vpnVos != null) {
                for (VpnVo vo : vpnVos) {
                    UserTodoDetailVO todo = new UserTodoDetailVO();
                    todo.setUserCode(userCode);
                    todo.setUserName(userEntity.getName());
                    todo.setDeptCode(userInfo.getCode());
                    todo.setOrgCode(userInfo.getOrgCode());
                    todo.setBusinessId(vo.getProcessId());
                    todo.setBusinessType("vpn");
                    todo.setBusinessTypeName("VPN审批");
                    todo.setTitle("VPN申请-" + vo.getApplicantName());
                    todo.setLink(appBaseUrl + "/#/examine/vpn?processId=" + vo.getProcessId());
                    allTodos.add(todo);
                }
            }

            FirewallDto firewallDto = new FirewallDto();
            firewallDto.setUserCode(userCode);
            List<FirewallVo> firewallVos = firewallExamineService.queryFirewallExamineDataNum(firewallDto);
            if (firewallVos != null) {
                for (FirewallVo vo : firewallVos) {
                    UserTodoDetailVO todo = new UserTodoDetailVO();
                    todo.setUserCode(userCode);
                    todo.setUserName(userEntity.getName());
                    todo.setDeptCode(userInfo.getCode());
                    todo.setOrgCode(userInfo.getOrgCode());
                    todo.setBusinessId(vo.getProcessId());
                    todo.setBusinessType("firewall");
                    todo.setBusinessTypeName("防火墙审批");
                    todo.setTitle("防火墙申请-" + vo.getContactPerson());
                    todo.setLink(appBaseUrl + "/#/examine/firewall?processId=" + vo.getProcessId());
                    allTodos.add(todo);
                }
            }

            NetMappingDto netMappingDto = new NetMappingDto();
            netMappingDto.setUserCode(userCode);
            List<NetMappingVo> netMappingVos = netMappingExamineService.queryNetMappingExamineDataNum(netMappingDto);
            if (netMappingVos != null) {
                for (NetMappingVo vo : netMappingVos) {
                    UserTodoDetailVO todo = new UserTodoDetailVO();
                    todo.setUserCode(userCode);
                    todo.setUserName(userEntity.getName());
                    todo.setDeptCode(userInfo.getCode());
                    todo.setOrgCode(userInfo.getOrgCode());
                    todo.setBusinessId(vo.getProcessId());
                    todo.setBusinessType("netMapping");
                    todo.setBusinessTypeName("网络映射审批");
                    todo.setTitle("网络映射申请-" + vo.getSystemLeaderName());
                    todo.setLink(appBaseUrl + "/#/examine/netMapping?processId=" + vo.getProcessId());
                    allTodos.add(todo);
                }
            }

            AccessDto accessDto = new AccessDto();
            accessDto.setUserCode(userCode);
            List<AccessVo> accessVos = accessExamineService.queryAccessExamineDataNum(accessDto);
            if (accessVos != null) {
                for (AccessVo vo : accessVos) {
                    UserTodoDetailVO todo = new UserTodoDetailVO();
                    todo.setUserCode(userCode);
                    todo.setUserName(userEntity.getName());
                    todo.setDeptCode(userInfo.getCode());
                    todo.setOrgCode(userInfo.getOrgCode());
                    todo.setBusinessId(vo.getProcessId());
                    todo.setBusinessType("access");
                    todo.setBusinessTypeName("Access审批");
                    todo.setTitle("Access申请-" + vo.getSystemOwnerName());
                    todo.setLink(appBaseUrl + "/#/examine/access?processId=" + vo.getProcessId());
                    allTodos.add(todo);
                }
            }

            SourceCodeAuditDto sourceCodeAuditDto = new SourceCodeAuditDto();
            sourceCodeAuditDto.setUserCode(userCode);
            List<SourceCodeAuditVo> sourceCodeAuditVos = sourceCodeAuditExamineService.querySourceCodeAuditExamineDataNum(sourceCodeAuditDto);
            if (sourceCodeAuditVos != null) {
                for (SourceCodeAuditVo vo : sourceCodeAuditVos) {
                    UserTodoDetailVO todo = new UserTodoDetailVO();
                    todo.setUserCode(userCode);
                    todo.setUserName(userEntity.getName());
                    todo.setDeptCode(userInfo.getCode());
                    todo.setOrgCode(userInfo.getOrgCode());
                    todo.setBusinessId(vo.getProcessId());
                    todo.setBusinessType("sourceCodeAudit");
                    todo.setBusinessTypeName("源代码审计审批");
                    todo.setTitle("源代码审计申请-" + vo.getSystemOwnerName());
                    todo.setLink(appBaseUrl + "/#/examine/sourceCodeAudit?processId=" + vo.getProcessId());
                    allTodos.add(todo);
                }
            }

            SecurityAssessmentDto securityAssessmentDto = new SecurityAssessmentDto();
            securityAssessmentDto.setUserCode(userCode);
            List<SecurityAssessmentVo> securityAssessmentVos = securityAssessmentExamineService.querySecurityAssessmentExamineDataNum(securityAssessmentDto);
            if (securityAssessmentVos != null) {
                for (SecurityAssessmentVo vo : securityAssessmentVos) {
                    UserTodoDetailVO todo = new UserTodoDetailVO();
                    todo.setUserCode(userCode);
                    todo.setUserName(userEntity.getName());
                    todo.setDeptCode(userInfo.getCode());
                    todo.setOrgCode(userInfo.getOrgCode());
                    todo.setBusinessId(vo.getProcessId());
                    todo.setBusinessType("securityAssessment");
                    todo.setBusinessTypeName("安全评估审批");
                    todo.setTitle("安全评估申请-" + vo.getSystemOwnerName());
                    todo.setLink(appBaseUrl + "/#/examine/securityAssessment?processId=" + vo.getProcessId());
                    allTodos.add(todo);
                }
            }
        }

        return allTodos;
    }

    @Override
    public String pushTodoToQzt(QztTodoDto todoDto) {
        try {
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            if (qztUsername != null && !qztUsername.isEmpty() && qztPassword != null && !qztPassword.isEmpty()) {
                String userPwd = qztUsername + ":" + qztPassword;
                String token = Base64Utils.encodeToString(userPwd.getBytes());
                headers.add("Authorization", "Basic " + token);
            }

            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("sysCode", todoDto.getSysCode());
            requestBody.put("moduleType", todoDto.getModuleType());
            requestBody.put("recType", todoDto.getRecType());
            requestBody.put("userCodes", todoDto.getUserCodes());
            requestBody.put("businessId", todoDto.getBusinessId());
            requestBody.put("title", todoDto.getTitle());
            requestBody.put("content", todoDto.getContent());
            requestBody.put("sendTime", todoDto.getSendTime());
            requestBody.put("status", todoDto.getStatus());
            requestBody.put("link", todoDto.getLink());
            requestBody.put("linkMobile", todoDto.getLinkMobile());
            requestBody.put("sendName", todoDto.getSendName());
            requestBody.put("sendCode", todoDto.getSendCode());
            requestBody.put("deptCode", todoDto.getDeptCode());
            requestBody.put("orgCode", todoDto.getOrgCode());
            requestBody.put("priority", todoDto.getPriority());

            HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);

            ResponseEntity<String> response = restTemplate.postForEntity(
                    qztApiUrl + "/provider-info/lanchProviderInfo.action",
                    entity,
                    String.class
            );

            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> respBody = objectMapper.readValue(response.getBody(), Map.class);
            String stateFlag = (String) respBody.get("stateFlag");

            if ("01".equals(stateFlag)) {
                return "success";
            } else {
                String msg = (String) respBody.get("msg");
                return "fail: " + (msg != null ? msg : "未知错误");
            }
        } catch (Exception e) {
            logger.error("推送待办到气政通失败", e);
            return "fail: " + e.getMessage();
        }
    }

    @Override
    public String deleteTodoFromQzt(QztTodoDto todoDto) {
        todoDto.setStatus("03");
        return pushTodoToQzt(todoDto);
    }

    @Override
    public void syncAllTodosToQzt() {
        logger.info("开始同步待办到气政通...");
        
        List<UserTodoDetailVO> allTodos = queryAllUserTodos();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String sendTime = sdf.format(new Date());

        Map<String, List<UserTodoDetailVO>> userTodoMap = new HashMap<>();
        for (UserTodoDetailVO todo : allTodos) {
            String userKey = todo.getUserCode();
            userTodoMap.computeIfAbsent(userKey, k -> new ArrayList<>()).add(todo);
        }

        int successCount = 0;
        int failCount = 0;

        for (Map.Entry<String, List<UserTodoDetailVO>> entry : userTodoMap.entrySet()) {
            String userCode = entry.getKey();
            List<UserTodoDetailVO> userTodos = entry.getValue();
            
            if (userTodos.isEmpty()) {
                continue;
            }

            UserTodoDetailVO firstTodo = userTodos.get(0);
            int todoCount = userTodos.size();
            
            Map<String, Integer> typeCountMap = new HashMap<>();
            for (UserTodoDetailVO todo : userTodos) {
                typeCountMap.put(todo.getBusinessTypeName(), 
                    typeCountMap.getOrDefault(todo.getBusinessTypeName(), 0) + 1);
            }
            
            StringBuilder contentBuilder = new StringBuilder();
            for (Map.Entry<String, Integer> typeEntry : typeCountMap.entrySet()) {
                if (contentBuilder.length() > 0) {
                    contentBuilder.append("、");
                }
                contentBuilder.append(typeEntry.getKey()).append(typeEntry.getValue()).append("条");
            }

            QztTodoDto todoDto = new QztTodoDto();
            todoDto.setSysCode(sysCode);
            todoDto.setModuleType("01");
            todoDto.setRecType("01");
            todoDto.setUserCodes(userCode);
            todoDto.setBusinessId("TODO_" + userCode + "_" + System.currentTimeMillis());
            todoDto.setTitle("您有" + todoCount + "条待办需要处理，请注意查收！");
            todoDto.setContent(contentBuilder.toString());
            todoDto.setSendTime(sendTime);
            todoDto.setStatus("01");
            todoDto.setLink(appBaseUrl+userCode);
            todoDto.setLinkMobile("");
            todoDto.setSendName(sysName);
            todoDto.setSendCode(sysCode);
            todoDto.setDeptCode(firstTodo.getDeptCode());
            todoDto.setOrgCode(firstTodo.getOrgCode());
            todoDto.setPriority(0);

            String result = pushTodoToQzt(todoDto);
            if ("success".equals(result)) {
                successCount++;
                logger.info("推送待办成功: userCode={}, todoCount={}", userCode, todoCount);
            } else {
                failCount++;
                logger.warn("推送待办失败: userCode={}, todoCount={}, result={}", 
                        userCode, todoCount, result);
            }
        }

        logger.info("同步待办完成: 成功={}, 失败={}, 总用户数={}, 总待办数={}", 
                successCount, failCount, userTodoMap.size(), allTodos.size());
    }
}
